#ifndef PCONVERTOR_H_
#define PCONVERTOR_H_

#include <vector>
#include <iterator>
#include <string>
#include <memory>
#include <cstdlib>
#include <typeinfo>
#include <cstring>

namespace PComunicator
{


//! Definicia byte ako datoveho typu 
/*!
 	byte predstavuje datovy typ ktory je reprezentovany ako unsigned char
*/
typedef unsigned char byte;


//! PConvertor staticka trieda. 
/*!
 	Staticka trieda urcena na konverziu medzi roznimi datovimi typmi
*/
class PConvertor
{
	public:
		~PConvertor(void);

		//! FromBasicType
		/*!
			Funkcia na prevod lubovolneho zakladneho datoveho typu na pole byte (unsigned char)
			\param theValue hodnota zakladneho datoveho typu ktora sa prekonvertuje
			\return zakodovana hodnota do pola byte, alebo prazdny vector ak sa nejedna o
					zakladny datovy typ udany ako parameter funckie
		*/
		template<typename T> static std::vector<byte> FromBasicType(T theValue)
		{
			if(!IsBasicType<T>(theValue))
			{
				std::vector<byte> anEmptyVector;
				return anEmptyVector;
			}

			byte aArray[sizeof(theValue)];
			memcpy(aArray,&theValue,sizeof(theValue));

			std::vector<byte> aResult(aArray,aArray+sizeof(theValue));
			return aResult;
		}
		
		//! ToBasicType
		/*!
			Funkcia na prevod pola byte v ktorom je zadokovana nejaky zakladny datovy typ
			na dany datovy typ
			\param pole byte
			\return data zakladneho datoveho typu
		*/
		template<typename T> static T ToBasicType(std::vector<byte> theValue)
		{
			T aResult;
			memcpy(&aResult,&theValue[0],theValue.size());

			return aResult;
		}


		//! FromInt
		/*!
			Funkcia na prevod datoveho typu int na pole byte (unsigned char)
			\param theValue hodnota typu int ktora sa prekonvertuje
			\return zakodovana hodnota do pola byte
		*/
		//static std::vector<byte> FromInt(int theValue);
		
		//! FromLong
		/*!
			Funkcia na prevod datoveho typu long na pole byte (unsigned char)
			\param theValue hodnota typu long ktora sa prekonvertuje
			\return zakodovana hodnota do pola byte
		*/
		//static std::vector<byte> FromLong(long theValue);

		//! FromString
		/*!
			Funkcia na prevod datoveho typu std::string na pole byte (unsigned char)
			\param theValue hodnota typu std::string ktora sa prekonvertuje
			\return zakodovana hodnota do pola byte
		*/
		static std::vector<byte> FromString(std::string theValue);
		
		//! FromString
		/*!
			Funkcia na prevod datoveho typu std::wstring(wide string) teda unicode retazca na pole byte (unsigned char)
			\param theValue hodnota typu std::wstring(wide string) ktora sa prekonvertuje
			\return zakodovana hodnota do pola byte
		*/
		static std::vector<byte> FromString(std::wstring theValue);

		//! ToInt
		/*!
			Funkcia na prevod pola byte(unsigned char), ktora v sebe obsahuje zakodovanu hodnotu
			datoveho typu int, na samotny datovy typ
			\param theValue pole byte obsahujuca encodovane data
			\return hodnota typu int ktora bola zakodovana do pola byte
		*/
		//static int ToInt(std::vector<byte> theValue);

		//! ToLong
		/*!
			Funkcia na prevod pola byte(unsigned char), ktora v sebe obsahuje zakodovanu hodnotu
			datoveho typu long, na samotny datovy typ
			\param theValue pole byte obsahujuca encodovane data
			\return hodnota typu long ktora bola zakodovana do pola byte
		*/
		//static long ToLong(std::vector<byte> theValue);

		//! ToString
		/*!
			Funkcia na prevod pola byte(unsigned char), ktora v sebe obsahuje zakodovanu hodnotu
			datoveho typu std::string, na samotny datovy typ
			\param theValue pole byte obsahujuca encodovane data
			\return hodnota typu std::string ktora bola zakodovana do pola byte
		*/
		static std::string ToString(std::vector<byte> theValue);

		//! ToString
		/*!
			Funkcia na prevod pola byte(unsigned char), ktora v sebe obsahuje zakodovanu hodnotu
			datoveho typu std::wstring, na samotny datovy typ
			\param theValue pole byte obsahujuca encodovane data
			\return hodnota typu std::wstring ktora bola zakodovana do pola byte
		*/
		static std::wstring ToWString(std::vector<byte> theValue);


	private:
		PConvertor(void);
		static void NullArray(char *pArray,int theSize);
		template<typename T> static bool IsBasicType(T theValue)
		{
			if(typeid(int) == typeid(T))
			{
				return true;
			}
			else if(typeid(unsigned int) == typeid(T))
			{
				return true;
			}
			else if(typeid(short) == typeid(T))
			{
				return true;
			}
			else if(typeid(unsigned short) == typeid(T))
			{
				return true;
			}
			else if(typeid(long) == typeid(T))
			{
				return true;
			}
			else if(typeid(unsigned long) == typeid(T))
			{
				return true;
			}
			else if(typeid(long long) == typeid(T))
			{
				return true;
			}
			else if(typeid(float) == typeid(T))
			{
				return true;
			}
			else if(typeid(double) == typeid(T))
			{
				return true;
			}
			return false;
		}
};

}

#endif
